package com.jic.market.orm;

import com.jic.market.holder.UserThreadLocalHolder;
import com.jic.market.model.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;

import java.lang.reflect.Field;
import java.util.Properties;

/**
 * description: MapperIntercept
 * date: 2020/2/26 14:18
 * author: wangys
 * version: 1.0
 */
@Intercepts( {
        @Signature(type = Executor.class, method = "update", args = {MappedStatement.class,
                Object.class})
})
@Slf4j
public class MapperIntercept implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        try {
            LoginUser user = UserThreadLocalHolder.CURRENT_USER.get();
            MappedStatement mappedStatement = (MappedStatement)invocation.getArgs()[0];
            SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
            Object parameter = invocation.getArgs()[1];
            Class<?> aClass = parameter.getClass();
            if(sqlCommandType.equals(SqlCommandType.INSERT)){
                Field creator = aClass.getDeclaredField("creator");
                Field creatorName = aClass.getDeclaredField("creatorName");
                Field updator = aClass.getDeclaredField("updator");
                Field updatorName = aClass.getDeclaredField("updatorName");
                creator.setAccessible(true);
                creatorName.setAccessible(true);
                creator.set(parameter, user.getId());
                creatorName.set(parameter, user.getUsername());
                updator.setAccessible(true);
                updatorName.setAccessible(true);
                updator.set(parameter, user.getId());
                updatorName.set(parameter, user.getUsername());
            }else if(sqlCommandType.equals(SqlCommandType.UPDATE)){
                Field updator = aClass.getDeclaredField("updator");
                Field updatorName = aClass.getDeclaredField("updatorName");
                updator.setAccessible(true);
                updatorName.setAccessible(true);
                updator.set(parameter, user.getId());
                updatorName.set(parameter, user.getUsername());
            }
        } catch (Exception e) {
            log.error("MapperIntercept error, e",e);
        }
        Object result = invocation.proceed();
        return result;
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}
